package com.newear.util;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.support.v4.util.ArrayMap;

import com.newear.message.MessageDispatcher;
import com.newear.message.MessageType;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 数据转换工具类
 * Created by josan_tang on 2016/07/19.
 */
public class DataConverter {
    private static final String TAG = "DataConverter";

    private static final String[] monthArr = {"Jua","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    private static final String[] dayArr = {"01st","02nd","03rd","04th","05th","06th","07th","08th","09th","10th","11th","12th","13th","14th","15th","16th","17th","18th","19th","20th",
            "21st","22nd","23rd","24th","25th","26th","27th","28th","29th","30th","31st"};
    /**
     * String -> Int
     *
     * @param strInt
     * @return null or empty return 0
     */
    public static int parseInt(String strInt) {
        return parseInt(strInt, 0);
    }

    /**
     * String -> Int
     *
     * @param strInt
     * @param defaultValue 当要转换的字符串不是数字时，默认返回数值
     * @return
     */
    public static int parseInt(String strInt, int defaultValue) {
        if (strInt == null || "".equals(strInt)) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(strInt);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 得到 md5
     *
     * @param source
     * @return 32 characters which represent a 128 bits long integer
     */
    public static String getMD5(byte[] source) {
        String s = "";
        try {
            java.security.MessageDigest md = java.security.MessageDigest
                    .getInstance("MD5");
            md.update(source);
            s = convertMD5(md.digest());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }

    public static String convertMD5(byte[] byteMD5) {
        // 用来将字节转换成 16 进制表示的字符
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f'};
        char str[] = new char[16 * 2]; // 每个字节用 16 进制表示的话，使用两个字符， 所以表示成 16 进制需要
        // 32 个字符
        int k = 0; // 表示转换结果中对应的字符位置
        for (int i = 0; i < 16; i++) { // 从第一个字节开始，对 MD5 的每一个字节 转换成 16 进制字符的转换
            byte byte0 = byteMD5[i]; // 取第 i 个字节
            str[k++] = hexDigits[byte0 >>> 4 & 0xf]; // 取字节中高 4 位的数字转换, // >>>
            // 为逻辑右移，将符号位一起右移
            str[k++] = hexDigits[byte0 & 0xf]; // 取字节中低 4 位的数字转换
        }
        return new String(str); // 换后的结果转换为字符串
    }

    /**
     * 通过map生成请求参数
     *
     * @return
     */
    public static String createParamByMap(ArrayMap<String, String> params) {
        StringBuffer result = new StringBuffer();
        Set paramSet = params.entrySet();
        Iterator iterator = paramSet.iterator();
        while (iterator.hasNext()) {
            Map.Entry mapEntry = (Map.Entry) iterator.next();
            result.append(mapEntry.getKey() + "=" + mapEntry.getValue() + "&");
        }
        return result.substring(0, result.length() - 1);
    }

    /**
     * 根据图片路径得到Bitmap对象
     *
     * @param path
     * @return
     */
    public static Bitmap getBitmapFormFilePath(String path, int height, int width) {
        try {
            //先解析图片边框的大小
            BitmapFactory.Options ops = new BitmapFactory.Options();
            ops.inJustDecodeBounds = true;
            Bitmap bitmap = BitmapFactory.decodeFile(path, ops);
            ops.inSampleSize = 1;
            int oHeight = ops.outHeight;
            int oWidth = ops.outWidth;
            //控制压缩比
            int contentHeight = height;
            int contentWidth = width;

            if (((float) oHeight / contentHeight) < ((float) oWidth / contentWidth)) {
                ops.inSampleSize = (int) Math.ceil((float) oWidth / contentWidth);
            } else {
                ops.inSampleSize = (int) Math.ceil((float) oHeight / contentHeight);
            }
            ops.inJustDecodeBounds = false;
            bitmap = BitmapFactory.decodeFile(path, ops);
            return bitmap;
        } catch (Exception e) {
            MyLogger.e(TAG, "getBitmapFormFilePath error!");
            return null;
        }
    }

    /**
     * 根据Uri得到真实路径
     *
     * @param uri
     * @return
     */
    public static String getRealPathFromURI(Context context, Uri uri) {
        try {
            String res = null;
            String[] proj = {MediaStore.Images.Media.DATA};
            Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null);
            if (cursor.moveToFirst()) {
                int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                res = cursor.getString(columnIndex);
            }
            cursor.close();
            return res;
        } catch (Exception e) {
            MyLogger.e(TAG, "getRealPathFromURI error");
            return null;
        }
    }

    /**
     * 根据Bitmap生成文件路径
     *
     * @param bm
     * @param path
     * @throws IOException
     */
    public static void getFilePathByBitmap(final Handler handler, final Bitmap bm, final String path, final int action) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    File file = new File(path);
                    if (file.exists()) {
                        file.delete();
                    }
                    FileOutputStream out;
                    try {
                        out = new FileOutputStream(file);
                        if (bm.compress(Bitmap.CompressFormat.PNG, 90, out)) {
                            out.flush();
                            out.close();
                        }
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                MessageDispatcher.sendMessage(handler, MessageType.SAVE_AVATAR_FINISHED, action);
            }
        }).start();
    }

    /**
     * 根据Bitmap生成文件路径
     *
     * @param bm
     * @param path
     * @throws IOException
     */
    public static void saveBitmap(final Bitmap bm, final String path) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    File file = new File(path);
                    if (file.exists()) {
                        file.delete();
                    }
                    FileOutputStream out;
                    try {
                        out = new FileOutputStream(file);
                        if (bm.compress(Bitmap.CompressFormat.PNG, 90, out)) {
                            out.flush();
                            out.close();
                        }
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 根据bitmap得到uri
     *
     * @param bitmap
     * @return
     */
    public static Uri getUriByBitmap(Bitmap bitmap) {
        File tmpDir = new File(Environment.getExternalStorageDirectory() + "/img");
        if (!tmpDir.exists()) {
            tmpDir.mkdir();
        }
        File img = new File(tmpDir.getAbsolutePath() + "/scan.png");
        try {
            FileOutputStream fos = new FileOutputStream(img);
            bitmap.compress(Bitmap.CompressFormat.PNG, 85, fos);
            fos.flush();
            fos.close();
            return Uri.fromFile(img);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 得到当前时间
     *
     * @return eg:2015-08-06 18:56:01
     */
    public static String getCurDayTime() {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date currentTime = new Date();
        String dayTime = formatter.format(currentTime);
        return dayTime;
    }

    /**
     * 得到当前时间
     *
     * @return eg:2015-08-06 18:56:01
     */
    public static String getCurDayTime(String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        Date currentTime = new Date();
        String dayTime = formatter.format(currentTime);
        return dayTime;
    }

    /**
     * 转换uri
     *
     * @param uri
     * @return
     */
    public static Uri convertUri(Context context, Uri uri) {
        InputStream is = null;
        try {
            is = context.getContentResolver().openInputStream(uri);
            if (is != null) {
                Bitmap bitmap = BitmapFactory.decodeStream(is);
                is.close();
                return getUriByBitmap(bitmap);
            }
        } catch (FileNotFoundException e) {

            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

        return null;
    }

    public static String urlDecode(String str) {
        if (null == str || "".equals(str)) {
            return "";
        } else {

            return URLDecoder.decode(str);
        }
    }

    /*时间戳转换成字符窜*/
    public static String getDateToString(long time) {
        Date d = new Date(time);
        SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日");
        return sf.format(d);
    }

    /*将字符串转为时间戳*/
    public static long getStringToDate(String time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        Date date = new Date();
        try {
            date = sdf.parse(time);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return date.getTime();
    }

    /**
     * 根据距离算得到特定格式距离
     * 规则：
     * 500 -> 500m
     * 1200 -> 1km
     * 1600 -> 2Km
     * 100000 -> 100+ km
     * @param distance 距离，单位 m
     * @return
     */
    public static String getStringByDistance(String distance) {
        String result = "";
        if (!Validator.isEffective(distance)) {
            return "";
        }
        try {
            int dis = (int) Double.parseDouble(distance);
            if (dis < 0) {
                return "";
            }
            if (dis <= 999) {
                return result + " m";
            }

            if (dis < 100000) {
                DecimalFormat df = new DecimalFormat(".0");
                return df.format((dis / 1000.0)) + " km";
            }

            if (dis > 100000) {
                return "100+ km";
            }
        } catch (Exception e) {
            return "";
        }

       return result;
    }

    /**
     * 得到裁剪图片url
     * @param imageUrl
     * @param action:0,等比缩放；1-裁剪
     * @param width：
     * @param height
     * @return
     */
    public static String getCutImageUrl(String imageUrl, int width, int height, int action) {
        String result = imageUrl;
        if (!Validator.isEffective(imageUrl)) {
            return  "";
        }
        result += "?w=" + width + "&h=" +height + "&c=" + action;
        return result;
    }

    /**
     * 得到Event模块中的日期
     * @param month 月份
     * @param day 日期
     * @return result[0] = 月份；result[1]=日期
     */
    public static String[] getEventDateFrom(int month, int day) {
        try {
            String result[] = new String[2];
            result[0] = monthArr[month-1];
            result[1] = dayArr[day-1];
            return result;
        } catch (Exception e) {
        }
        return null;
    }

    /**
     * 得到时间差
     * @param startDate
     * @param endDate
     * @return
     */
    public static long getDateDistance(String startDate, String endDate) {
        long distance = 0;
        try {
            //设定时间的模板
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //得到指定模范的时间
            long d1 = sdf.parse(startDate).getTime();
            long d2 = sdf.parse(endDate).getTime();
            distance = d2 - d1;
            MyLogger.i("getDateDistance:" + distance);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return  distance;
    }
}
